﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;

namespace BadHabit.WPFTools {

    /// <summary>
    /// Provides a easy way to hide UI Elements based on the current thread IsInRole method.
    /// </summary>
    public class RoleChecker {


        public static readonly DependencyProperty RequiredVisibleRoleProperty = DependencyProperty.RegisterAttached(
            "RequiredVisibleRole",
            typeof(String),
            typeof(RoleChecker),
            new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.AffectsRender, new PropertyChangedCallback(OnRequiredRoleChanged)));

        public static readonly DependencyProperty RequiredEnableRoleProperty = DependencyProperty.RegisterAttached(
            "RequiredEnableRole",
            typeof(String),
            typeof(RoleChecker),
            new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.AffectsRender, new PropertyChangedCallback(OnRequiredRoleChanged)));

        public static readonly DependencyProperty RequiredEditRoleProperty = DependencyProperty.RegisterAttached(
            "RequiredEditRole",
            typeof(String),
            typeof(RoleChecker),
            new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.AffectsRender, new PropertyChangedCallback(OnRequiredRoleChanged)));

       

        public static void SetRequiredVisibleRole(Control control, String value) {
            control.SetValue(RequiredVisibleRoleProperty, value);
            SetVisibility(control);
        }

        public static String GetRequiredVisibleRole(Control control) {
            return (String)control.GetValue(RequiredVisibleRoleProperty);
        }

        public static void SetRequiredEnableRole(Control control, String value) {
            control.SetValue(RequiredEnableRoleProperty, value);
            SetEnableality(control);
        }

        public static String GetRequiredEnableRole(Control control) {
            return (String)control.GetValue(RequiredEnableRoleProperty);
        }

        public static void SetRequiredEditRole(Control control, String value) {
            control.SetValue(RequiredEditRoleProperty, value);
            SetEnableality(control);
        }

        public static String GetRequiredEditRole(Control control) {
            return (String)control.GetValue(RequiredEditRoleProperty);
        }

        public static System.Security.Principal.GenericPrincipal ThreadPrincipal { get; set; }

        private static void OnRequiredRoleChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) {
            if (!(d is FrameworkElement))
                throw new Exception("RequiredVisibleRole/RequiredEnableRole Property should be attached to a FrameworkElement only.");



            FrameworkElement control = d as FrameworkElement;
            control.Loaded += new RoutedEventHandler(control_Loaded);
        }



        static void control_Loaded(object sender, RoutedEventArgs e) {
            SetVisibility((FrameworkElement)sender);
            SetEnableality((FrameworkElement)sender);
            SetReadOnly((FrameworkElement)sender);
        }

        private static void SetVisibility(FrameworkElement control) {

            object o = control.GetValue(RequiredVisibleRoleProperty);
    
            
            if (o == null) {                
                return;
            }

            if (ThreadPrincipal == null) {
                control.Visibility = Visibility.Collapsed;
                return;
            }

            if (!ThreadPrincipal.IsInRole(o.ToString()))
                control.Visibility = Visibility.Collapsed;
        }

        private static void SetEnableality(FrameworkElement control) {

            object o = control.GetValue(RequiredEnableRoleProperty);


            if (o == null) {                
                return;
            }

            if (ThreadPrincipal == null) {                
                return;
            }

            if (!ThreadPrincipal.IsInRole(o.ToString()))
                control.IsEnabled = false;
            else
                control.IsEnabled = true;
        }


        private static void SetReadOnly(FrameworkElement control) {

            object o = control.GetValue(RequiredEditRoleProperty);

            if (o == null) {
                return;
            }

            TextBox textBox = control as TextBox;
            if (textBox != null) {
                if (ThreadPrincipal == null) {
                    textBox.IsReadOnly = true;
                    return;
                }

                if (!ThreadPrincipal.IsInRole(o.ToString()))
                    textBox.IsReadOnly = true;
                else
                    textBox.IsReadOnly = false;

                return;
            }

            ComboBox comboBox = control as ComboBox;
            if (comboBox != null) {
                if (ThreadPrincipal == null) {
                    comboBox.IsReadOnly = true;
                    return;
                }

                if (!ThreadPrincipal.IsInRole(o.ToString()))
                    comboBox.IsReadOnly = true;
                else
                    comboBox.IsReadOnly = false;

                return;
            }

            Microsoft.Windows.Controls.DataGrid datagrid = control as Microsoft.Windows.Controls.DataGrid;
            if (datagrid != null) {
                if (ThreadPrincipal == null) {
                    datagrid.IsReadOnly = true;
                    return;
                }

                if (!ThreadPrincipal.IsInRole(o.ToString()))
                    datagrid.IsReadOnly = true;
                else
                    datagrid.IsReadOnly = false;

                return;
            }
                       
            
            throw new Exception("RequiredEditRole can noly be used at TextBoxes, ComboBoxes and DatagGrid.");

            
        }


      

    }
}





